package org.jsola.hr.service.impl;

import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageHelper;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IOperationEmpRecordDAO;
import org.jsola.hr.dto.OperationEmpRecordAddDTO;
import org.jsola.hr.dto.OperationEmpRecordUpdateDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.entity.GroupCompanyDO;
import org.jsola.hr.entity.OperationEmpRecordDO;
import org.jsola.hr.query.OperationEmpRecordQuery;
import org.jsola.hr.service.ICheckInPeopleService;
import org.jsola.hr.service.IChildCompanyService;
import org.jsola.hr.service.IGroupCompanyService;
import org.jsola.hr.service.IOperationEmpRecordService;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 操作员工记录表
 *
 * @author zhr
 */
@Service("hrOperationEmpRecordServiceImpl")
@Slf4j
public class OperationEmpRecordServiceImpl implements IOperationEmpRecordService {

    @Autowired
    private IOperationEmpRecordDAO operationEmpRecordDAO;

    @Autowired
    private ICheckInPeopleService checkInPeopleService;

    @Autowired
    private IChildCompanyService childCompanyService;

    @Autowired
    private IGroupCompanyService groupCompanyService;


    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Void currencyAdd(String companyId, Integer queryType, String userId, String empId, String checkInId,
                            Integer empStatus, Integer sourceType, String sourceTypeInfo, String methodPath, TokenUser tokenUser) {
        try {
            OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
            if (!StringUtils.isEmpty(companyId)) {
                operationEmpRecordAddDTO.setCompanyId(companyId);
            }
            operationEmpRecordAddDTO.setQueryType(queryType);
            if (!StringUtils.isEmpty(userId)) {
                operationEmpRecordAddDTO.setUserId(userId);
            }
            if (!StringUtils.isEmpty(empId)) {
                operationEmpRecordAddDTO.setEmpId(empId);
            }
            if (!StringUtils.isEmpty(checkInId)) {
                operationEmpRecordAddDTO.setCheckInId(checkInId);
            }
            operationEmpRecordAddDTO.setEmpStatus(empStatus);
            operationEmpRecordAddDTO.setSourceType(sourceType);
            operationEmpRecordAddDTO.setSourceTypeInfo(sourceTypeInfo);
            operationEmpRecordAddDTO.setMethodPath(methodPath);
            operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
            save(operationEmpRecordAddDTO, tokenUser);
            return null;
        } catch (Exception e) {
            log.error("员工记录异常");
        }
        return null;
    }

    @Override
    public Page<EmpInfoVO> queryEmpPageList(OperationEmpRecordQuery operationEmpRecordQuery, TokenUser tokenUser) {
        Date beginOfDay = null;
        Date endOfDay = null;
        if (operationEmpRecordQuery.getSortType() == null) {
            operationEmpRecordQuery.setSortType(2);
        }
        if (operationEmpRecordQuery.getDate() != null) {
            beginOfDay = DateUtil.beginOfDay(operationEmpRecordQuery.getDate());
            endOfDay = DateUtil.endOfDay(operationEmpRecordQuery.getDate());
        } else {
            beginOfDay = DateUtil.beginOfDay(new Date());
            endOfDay = DateUtil.endOfDay(new Date());
        }
        operationEmpRecordQuery.setStartTime(beginOfDay);
        operationEmpRecordQuery.setEndTime(endOfDay);
        String companyId = operationEmpRecordQuery.getCompanyId();
        UserCompanyVO userCompanyVO = childCompanyService.selectByUserId(tokenUser.getUserId(), tokenUser.getSiteId());
        // 非总公司权限 查询条件加入用户管理的公司
        if (!userCompanyVO.getIsAllChildCompany()) {
            List<String> companyIdList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(userCompanyVO.getCompanyIds())) {
                companyIdList.addAll(userCompanyVO.getCompanyIds());
            }
            if (!CollectionUtils.isEmpty(userCompanyVO.getGroupIds())) {
                List<GroupCompanyDO> groupCompanyDOList = groupCompanyService
                        .selectByGroupIds(userCompanyVO.getGroupIds(), tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(groupCompanyDOList)) {
                    companyIdList.addAll(groupCompanyDOList.parallelStream()
                            .map(GroupCompanyDO::getCompanyId).distinct().collect(Collectors.toList()));
                }
            }
            if (StringUtils.hasLength(companyId)) {
                if (companyIdList.contains(companyId)) {
                    companyIdList = Collections.singletonList(companyId);
                } else {
                    companyIdList = Collections.singletonList("");
                }
            }
            operationEmpRecordQuery.setCompanyIds(companyIdList);
        } else if (StringUtils.hasLength(companyId)) {
            operationEmpRecordQuery.setCompanyIds(Collections.singletonList(companyId));
        }
        com.github.pagehelper.Page<CheckInPeopleVO> page = PageHelper.startPage(operationEmpRecordQuery.getPageNo(), operationEmpRecordQuery.getPageSize());
        List<EmpInfoVO> empInfoVOList = operationEmpRecordDAO.queryEmp(operationEmpRecordQuery, tokenUser.getSiteId());
        Page<EmpInfoVO> page1 = new Page<>(operationEmpRecordQuery.getPageSize(), operationEmpRecordQuery.getPageNo());
        page1.setEntities(empInfoVOList);
        page1.setEntityCount((int) page.getTotal());
        page1.setPageCount(page.getPages());
        page1.setPageNo(operationEmpRecordQuery.getPageNo());
        page1.setPageSize(operationEmpRecordQuery.getPageSize());
        return page1;
    }

    @Override
    public Page<CheckInPeopleListVO> queryPageList(OperationEmpRecordQuery operationEmpRecordQuery, TokenUser tokenUser) {
        Date beginOfDay = null;
        Date endOfDay = null;
        if (operationEmpRecordQuery.getDate() != null) {
            beginOfDay = DateUtil.beginOfDay(operationEmpRecordQuery.getDate());
            endOfDay = DateUtil.endOfDay(operationEmpRecordQuery.getDate());
        } else {
            beginOfDay = DateUtil.beginOfDay(new Date());
            endOfDay = DateUtil.endOfDay(new Date());
        }
        operationEmpRecordQuery.setStartTime(beginOfDay);
        operationEmpRecordQuery.setEndTime(endOfDay);
        com.github.pagehelper.Page<CheckInPeopleListVO> page = PageHelper.startPage(operationEmpRecordQuery.getPageNo(), operationEmpRecordQuery.getPageSize());
        List<CheckInPeopleListVO> checkInPeopleVOList = operationEmpRecordDAO.queryCheckIn(operationEmpRecordQuery, tokenUser.getSiteId());
        for (CheckInPeopleListVO checkInPeopleListVO : checkInPeopleVOList) {
            checkInPeopleService.setHireDateAndCompanyName(checkInPeopleListVO, tokenUser.getSiteId());
        }
        Page<CheckInPeopleListVO> page1 = new Page<>();
        page1.setEntities(checkInPeopleVOList);
        page1.setEntityCount((int) page.getTotal());
        page1.setPageCount(page.getPages());
        page1.setPageNo(operationEmpRecordQuery.getPageNo());
        page1.setPageSize(operationEmpRecordQuery.getPageSize());
        return page1;
    }

    @Override
    public OperationEmpRecordListVO queryCount(OperationEmpRecordQuery operationEmpRecordQuery, TokenUser tokenUser) {
        int pcCount = 0;
        int appCount = 0;
        int changeCount = 0;
        Date beginOfDay = null;
        Date endOfDay = null;
        if (operationEmpRecordQuery.getDate() != null) {
            beginOfDay = DateUtil.beginOfDay(operationEmpRecordQuery.getDate());
            endOfDay = DateUtil.endOfDay(operationEmpRecordQuery.getDate());
        } else {
            beginOfDay = DateUtil.beginOfDay(new Date());
            endOfDay = DateUtil.endOfDay(new Date());
        }

        OperationEmpRecordListVO operationEmpRecordListVO = new OperationEmpRecordListVO();
        String companyId = operationEmpRecordQuery.getCompanyId();
        UserCompanyVO userCompanyVO = childCompanyService.selectByUserId(tokenUser.getUserId(), tokenUser.getSiteId());
        if (StringUtil.isNotBlank(companyId)) {
            // 非总公司权限 查询条件加入用户管理的公司
            if (!userCompanyVO.getIsAllChildCompany()) {
                List<String> companyIdList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(userCompanyVO.getCompanyIds())) {
                    companyIdList.addAll(userCompanyVO.getCompanyIds());
                }
                if (!CollectionUtils.isEmpty(userCompanyVO.getGroupIds())) {
                    List<GroupCompanyDO> groupCompanyDOList = groupCompanyService
                            .selectByGroupIds(userCompanyVO.getGroupIds(), tokenUser.getSiteId());
                    if (!CollectionUtils.isEmpty(groupCompanyDOList)) {
                        companyIdList.addAll(groupCompanyDOList.parallelStream()
                                .map(GroupCompanyDO::getCompanyId).distinct().collect(Collectors.toList()));
                    }
                }
                if (companyIdList.contains(companyId)) {
                    companyIdList = Collections.singletonList(companyId);
                } else {
                    companyIdList = Collections.singletonList("");
                }
                operationEmpRecordQuery.setCompanyIds(companyIdList);
            } else if (StringUtils.hasLength(companyId)) {
                operationEmpRecordQuery.setCompanyIds(Collections.singletonList(companyId));
            }
        } else if (!CollectionUtils.isEmpty(operationEmpRecordQuery.getCompanyIds())) {
            // 条件用工单位Ids和权限Ids 取交集
            if (!userCompanyVO.getIsAllChildCompany()) {
                List<String> companyIdList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(userCompanyVO.getCompanyIds())) {
                    companyIdList.addAll(userCompanyVO.getCompanyIds());
                }
                if (!CollectionUtils.isEmpty(userCompanyVO.getGroupIds())) {
                    List<GroupCompanyDO> groupCompanyDOList = groupCompanyService
                            .selectByGroupIds(userCompanyVO.getGroupIds(), tokenUser.getSiteId());
                    if (!CollectionUtils.isEmpty(groupCompanyDOList)) {
                        companyIdList.addAll(groupCompanyDOList.parallelStream()
                                .map(GroupCompanyDO::getCompanyId).distinct().collect(Collectors.toList()));
                    }
                }
                companyIdList.retainAll(operationEmpRecordQuery.getCompanyIds());
                operationEmpRecordQuery.setCompanyIds(companyIdList);
            }
        }
        //今日新增数量
        operationEmpRecordQuery.setStartTime(beginOfDay);
        operationEmpRecordQuery.setEndTime(endOfDay);
        List<OperationEmpRecordListVO> operationEmpRecordListVOS = operationEmpRecordDAO.queryCount(operationEmpRecordQuery, tokenUser.getSiteId());
        operationEmpRecordListVO.setAllCount(operationEmpRecordListVOS.size());
        for (OperationEmpRecordListVO empRecordListVO : operationEmpRecordListVOS) {
            if (empRecordListVO.getSourceType() == 1) {
                pcCount++;
            } else if (empRecordListVO.getSourceType() == 2) {
                appCount++;
            } else if (empRecordListVO.getSourceType() == 3) {
                changeCount++;
            }
        }
        operationEmpRecordListVO.setPcCount(pcCount);
        operationEmpRecordListVO.setAppCount(appCount);
        operationEmpRecordListVO.setChangeCount(changeCount);

        return operationEmpRecordListVO;


    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public OperationEmpRecordVO save(OperationEmpRecordAddDTO operationEmpRecordAddDTO, TokenUser tokenUser) {
        // 转DO
        OperationEmpRecordDO operationEmpRecordDO = operationEmpRecordAddDTO.to(OperationEmpRecordDO.class);
        // 保存
        operationEmpRecordDO = save(operationEmpRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return operationEmpRecordDO.to(OperationEmpRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(OperationEmpRecordUpdateDTO operationEmpRecordUpdateDTO, TokenUser tokenUser) {
        //转DO
        OperationEmpRecordDO operationEmpRecordDO = operationEmpRecordUpdateDTO.to(OperationEmpRecordDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(operationEmpRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... operationEmpRecordIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) operationEmpRecordIds);
    }


    @Override
    public OperationEmpRecordVO selectById(String operationEmpRecordId, String siteId) {
        OperationEmpRecordDO operationEmpRecordDO = selectDOById(operationEmpRecordId, siteId);
        if (operationEmpRecordDO == null) {
            return null;
        }
        return operationEmpRecordDO.to(OperationEmpRecordVO.class);
    }

    @Override
    public List<OperationEmpRecordListVO> select(OperationEmpRecordQuery operationEmpRecordQuery, String siteId) {
        List<OperationEmpRecordDO> operationEmpRecordDOList = selectDO(operationEmpRecordQuery, siteId);
        if (CollectionUtils.isEmpty(operationEmpRecordDOList)) {
            return operationEmpRecordDOList == null ? null : new ArrayList<>();
        }
        return operationEmpRecordDOList.stream()
                .map(operationEmpRecordDO -> operationEmpRecordDO.to(OperationEmpRecordListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(OperationEmpRecordQuery operationEmpRecordQuery, String siteId) {
        Example example = buildExample(operationEmpRecordQuery, siteId);
        return operationEmpRecordDAO.selectCountByExample(example);
    }

    @Override
    public Page<OperationEmpRecordListVO> selectPage(OperationEmpRecordQuery operationEmpRecordQuery, String siteId) {
        Example example = buildExample(operationEmpRecordQuery, siteId);
        Page<OperationEmpRecordDO> page = operationEmpRecordDAO.selectPageByExample(example,
                operationEmpRecordQuery.getPageNo(),
                operationEmpRecordQuery.getPageSize());

        return page.to(OperationEmpRecordListVO.class);
    }

    @Override
    public OperationEmpRecordDO selectDOById(String operationEmpRecordId, String siteId) {
        return listById(operationEmpRecordId, siteId);
    }

    @Override
    public List<OperationEmpRecordDO> selectDO(OperationEmpRecordQuery operationEmpRecordQuery, String siteId) {
        Example example = buildExample(operationEmpRecordQuery, siteId);
        return operationEmpRecordDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void importEmpBatchSave(List<EmpInfoDO> empInfoAddList, TokenUser tokenUser) {
        try {
            List<OperationEmpRecordDO> insertList = new ArrayList<>();
            for (EmpInfoDO empInfoDO : empInfoAddList) {
                OperationEmpRecordDO insert = new OperationEmpRecordDO();
                insert.setEmpId(empInfoDO.getId());
                insert.setEmpStatus(3);
                insert.setQueryType(2);
                insert.setInputUserId(tokenUser.getUserId());
                insert.setUserId(empInfoDO.getUserId());
                insert.setSourceType(1);
                insert.setSourceTypeInfo("PC入职");
                insert.setCompanyId(empInfoDO.getCompanyId());
                insert.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveExcelDataList");
                insert.setSiteId(tokenUser.getSiteId());
                insert.preInsert(tokenUser.getUserId());
                insertList.add(insert);
            }
            if (!CollectionUtils.isEmpty(insertList)) {
                operationEmpRecordDAO.insertListAndSetId(insertList);
            }
        } catch (Exception e) {
            log.error("员工记录异常");
        }
    }


    /**
     * 根据查询参数，构建example
     *
     * @param operationEmpRecordQuery 查询参数
     * @param siteId                  所属站点id
     * @return example
     */
    private Example buildExample(OperationEmpRecordQuery operationEmpRecordQuery, String siteId) {
        Example example = new Example(OperationEmpRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 排序
        if (!StringUtils.isEmpty(operationEmpRecordQuery.getEmpId())) {
            example.and().andEqualTo("empId", operationEmpRecordQuery.getEmpId());
        }
        if (operationEmpRecordQuery.getSourceTypeIsNull() != null && operationEmpRecordQuery.getSourceTypeIsNull()) {
            example.and().andIsNull("sourceType");
        }
        if (operationEmpRecordQuery.getSourceTypeIsNotNull() != null && operationEmpRecordQuery.getSourceTypeIsNotNull()) {
            example.and().andIsNotNull("sourceType");
        }
        if (!StringUtils.isEmpty(operationEmpRecordQuery.getCheckInId())) {
            example.and().andEqualTo("checkInId", operationEmpRecordQuery.getCheckInId());
        }
        if (operationEmpRecordQuery.getEmpStatus() != null) {
            example.and().andEqualTo("empStatus", operationEmpRecordQuery.getEmpStatus());
        }
        ExampleKit.setExampleOrder(example, operationEmpRecordQuery.getOrders());
        return example;
    }
}




